﻿#pragma once
#include "Support/AnalyseTree/AnalyseTree.h"
#include "../CommonIOStuct.h"

enum class _eTitleslevel	// 头衔等级
{
	Baron,
	Count,
	Duke,
	King,
	Empire,
	Max,
};

static const std::wstring c_TitleLevelEnum2String[] = {
	L"Baron",
	L"Count",
	L"Duke",
	L"King",
	L"Emperor"
};

static const std::wstring c_TitlesLandedEnum2String[] = {
	L"Baron",
	L"Count",
	L"Duke",
	L"Kingdom",
	L"Empire"
};

_STATIC_ASSERT(sizeof(c_TitleLevelEnum2String) != (int)_eTitleslevel::Max);
_STATIC_ASSERT(sizeof(c_TitlesLandedEnum2String) != (int)_eTitleslevel::Max);

// 基础条目
// 继承之后方便多态赋值


struct _st_rebel
{
	bool m_b_rebel = false;		// 是否是叛军
};

struct _st_landless
{
	bool m_b_landless = false;	// 荣誉头衔 Always exists
};

struct _st_primary
{
	bool m_b_primary = false;	// Cannot be held as a secondary title
};

struct _st_tribe
{
	bool m_b_tribe = true;		// 部落可否使用此头衔
};

struct _st_pirate
{
	bool m_b_pirate = false;		// 是否是海盗
};

struct _st_creation_requires_capital
{
	bool m_b_creation_requires_capital = true;		// 创建头衔需要首都
};

struct _st_color
{
	std::vector<BYTE> m_vec_color;
};

struct _st_color2
{
	std::vector<BYTE> m_vec_color2;
};

struct _st_capital
{
	UINT16 m_n_capital = 0;		// 首都
};

struct _st_title
{
	std::wstring m_wstr_title;
};

struct _st_title_female
{
	std::wstring m_wstr_title_female;
};

struct _st_foa
{
	std::wstring m_wstr_foa;
};

struct _st_short_name
{
	bool m_b_short_name = false;
};

struct _st_location_ruler_title
{
	bool m_b_location_ruler_title = false;
};

struct _st_controls_religion
{
	std::wstring m_wstr_controls_religion;	// Controls a religion
};

struct _st_dynasty_title_names
{
	bool m_b_dynasty_title_names = true;	// Will not be named "Seljuk", etc.
};

struct _st_male_names
{
	std::vector<std::wstring> m_list_male_names;
};

struct _st_dignity
{
	UINT16 m_n_dignity = 0;		// Counted as having this many more counties than it does
};

struct _st_caliphate
{
	bool m_b_caliphate = false;		// 哈里发
};

struct _st_mercenary
{
	bool m_b_mercenary = false;		// 雇佣兵
};

struct _st_independent
{
	bool m_b_independent = false;	// Can/Cannot be vassalized
};

struct _st_strength_growth_per_century
{
	float m_f_strength_growth_per_century = 1.0f;	// 兵力增长/每100年
};

struct _st_mercenary_type
{
	std::wstring m_wstr_mercenary_type;		// 雇佣兵类型
};

struct _st_pentarchy
{
	bool m_b_pentarchy = false;		// 五大牧首区
};

struct _st_used_for_dynasty_names
{
	bool m_b_used_for_dynasty_names = true;		// 可被用作王朝名
};

struct _st_holy_site
{
	std::list<std::wstring>	m_list_holy_site;
};

struct _st_catholic
{
	int m_n_catholic = 0;		// Crusade target weight
};

struct _st_muslim
{
	int m_n_muslim = 0;		// Crusade target weight
};

struct _st_norse_pagan_reformed
{
	int m_n_norse_pagan_reformed = 0;		// Crusade target weight
};

struct _st_baltic_pagan_reformed
{
	int m_n_baltic_pagan_reformed = 0;		// Crusade target weight
};

struct _st_slavic_pagan_reformed
{
	int m_n_slavic_pagan_reformed = 0;		// Crusade target weight
};

struct _st_orthodox
{
	int m_n_orthodox = 0;		// Crusade target weight
};

struct _st_zoroastrian_group
{
	int m_n_zoroastrian_group = 0;		// Crusade target weight
};

struct _st_tengri_pagan_reformed
{
	int m_n_tengri_pagan_reformed = 0;		// Crusade target weight
};

struct _st_christian
{
	int m_n_christian = 0;		// Crusade target weight
};

struct _st_finnish_pagan_reformed
{
	int m_n_finnish_pagan_reformed = 0;		// Crusade target weight
};

struct _st_zun_pagan_reformed
{
	int m_n_zun_pagan_reformed = 0;		// Crusade target weight
};

struct _st_west_african_pagan_reformed
{
	int m_n_west_african_pagan_reformed = 0;		// Crusade target weight
};

struct _st_jewish_group
{
	int m_n_jewish_group = 0;		// Crusade target weight
};

struct _st_holy_order
{
	bool m_b_holy_order = false;
};

struct _st_monthly_income
{
	WORD m_n_monthly_income = 1;
};

struct _st_purple_born_heirs
{
	bool m_b_purple_born_heirs = false;
};

struct _st_has_top_de_jure_capital
{
	bool m_b_has_top_de_jure_capital = false;
};

struct _st_assimilate
{
	bool m_b_assimilate = true;		// Duchies cannot de jure drift OUT of this title
};

struct _st_data
{
	std::vector<BYTE> m_vec_data;
};

struct _st_texture
{
	BYTE m_n_texture = 0;
};

struct _st_texture_internal
{
	BYTE m_n_texture_internal = 0;
};

struct _st_emblem
{
	BYTE m_n_emblem = 0;
};

struct _st_template
{
	BYTE m_n_template = 0;
};


struct _st_Culture2Name
{
	std::map<std::wstring, std::wstring> m_map_Culture2Name;	// 不同文化的省份名  "italian" : "皮西诺" etc.
};




// 内嵌结构
struct _st_coat_of_arms : public
	_st_data,		// std::vector<BYTE> m_vec_data
	_st_religion	// std::wstring m_wstr_religion
{};

struct _st_layer : public
	_st_texture,			// BYTE m_n_texture
	_st_texture_internal,	// BYTE m_n_texture_internal
	_st_emblem,				// BYTE m_n_emblem
	_st_color				// std::vector<BYTE> m_vec_color
{};

struct _st_pagan_coa : public
	_st_template,		// BYTE m_n_template
	_st_religion		// std::wstring m_wstr_religion
{
	_st_layer m_st_layer;
};


// C继承A和B D继承C 用(DWORD)(D的this)转换成B将失败
// 多重继承转换时需要明确转换类型 应(B*)(D*)这样逐级转换
struct _stLandedTitlesProperty : public			// 使用std::move重构了拷贝构造函数,会是输入值失效
	_st_IndexName,						// std::wstring m_wstr_IndexName				Key 头衔索引名
	_st_rebel,							// bool m_b_rebel								是否是叛军
	_st_landless,						// bool m_b_landless							荣誉头衔 Always exists
	_st_primary,						// bool m_b_primary								Cannot be held as a secondary title
	_st_tribe,							// bool m_b_tribe								部落可否使用此头衔
	_st_pirate,							// bool m_b_pirate								是否是海盗
	_st_creation_requires_capital,		// bool m_b_creation_requires_capital			创建头衔需要首都
	_st_culture,						// std::wstring m_wstr_culture					文化
	_st_color,							// std::vector<BYTE> m_vec_color
	_st_color2,							// std::vector<BYTE> m_vec_color2
	_st_capital,						// UINT16 m_n_capital							首都
	_st_title,							// std::wstring m_wstr_title
	_st_title_female,					// std::wstring m_wstr_title_female
	_st_foa,							// std::wstring m_wstr_foa
	_st_short_name,						// bool m_b_short_name
	_st_location_ruler_title,			// bool m_b_location_ruler_title
	_st_controls_religion,				// std::wstring m_wstr_controls_religion		Controls a religion
	_st_religion,						// std::wstring m_wstr_religion					宗教
	_st_dynasty_title_names,			// bool m_b_dynasty_title_names					Will not be named "Seljuk", etc.
	_st_male_names,						// std::vector<std::wstring> m_list_male_names
	_st_dignity,						// UINT16 m_n_dignity							Counted as having this many more counties than it does
	_st_caliphate,						// bool m_b_caliphate							哈里发
	_st_mercenary,						// bool m_b_mercenary							雇佣兵
	_st_independent,					// bool m_b_independent							Can/Cannot be vassalized
	_st_strength_growth_per_century,	// float m_f_strength_growth_per_century		兵力增长/每100年
	_st_mercenary_type,					// std::wstring m_wstr_mercenary_type			雇佣兵类型
	_st_pentarchy,						// bool m_b_pentarchy							五大牧首区
	_st_used_for_dynasty_names,			// bool m_b_used_for_dynasty_names				可被用作王朝名
	_st_holy_site,						// std::list<std::wstring>	m_list_holy_site;
	_st_Culture2Name,					// std::map<std::wstring, std::wstring> m_map_Culture2Name			"italian" : "皮西诺" etc.
	_st_catholic,						// int m_n_catholic;							Crusade target weight
	_st_muslim,							// int m_n_muslim;								Crusade target weight
	_st_norse_pagan_reformed,			// int m_n_norse_pagan_reformed					Crusade target weight
	_st_baltic_pagan_reformed,			// int m_n_baltic_pagan_reformed				Crusade target weight
	_st_slavic_pagan_reformed,			// int m_n_slavic_pagan_reformed				Crusade target weight
	_st_orthodox,						// int m_n_orthodox								Crusade target weight
	_st_zoroastrian_group,				// int m_n_zoroastrian_group					Crusade target weight
	_st_tengri_pagan_reformed,			// int m_n_tengri_pagan_reformed				Crusade target weight
	_st_christian,						// int m_n_christian							Crusade target weight
	_st_finnish_pagan_reformed,			// int m_n_finnish_pagan_reformed				Crusade target weight
	_st_zun_pagan_reformed,				// int m_n_zun_pagan_reformed					Crusade target weight
	_st_west_african_pagan_reformed,	// int m_n_west_african_pagan_reformed			Crusade target weight
	_st_jewish_group,					// int m_n_jewish_group							Crusade target weight
	_st_holy_order,						// bool m_b_holy_order
	_st_monthly_income,					// WORD m_n_monthly_income						Must be an integer between 1 and 512
	_st_purple_born_heirs,				// bool m_b_purple_born_heirs
	_st_has_top_de_jure_capital,		// bool m_b_has_top_de_jure_capital
	_st_assimilate						// bool m_b_assimilate							Duchies cannot de jure drift OUT of this title
{
public:
	_st_coat_of_arms m_st_coat_of_arms;
	_st_pagan_coa m_st_pagan_coa;
public:
	_stLandedTitlesProperty() = default;
	~_stLandedTitlesProperty() = default;
	_stLandedTitlesProperty(_stLandedTitlesProperty& st);		// 使用std::move 不能用const修饰 导致不能储存在list中 list::back()之类的方法要调用
	_stLandedTitlesProperty& operator =(const _stLandedTitlesProperty&) = delete;

	std::wstring GetIndexName() const { return m_wstr_IndexName; }

	bool empty() const;

	_eTitleslevel m_eTitleslevel = _eTitleslevel::Baron;	// 头衔等级
	
	std::unique_ptr<AnalyseTreeNodeCondition> m_p_allow;

	_stLandedTitlesProperty* m_pFatherTitle = nullptr;	// 上级头衔
	std::list<_stLandedTitlesProperty*> m_listChildTitles;	// 下级头衔
};



class CLandedTitlesProperty
{
	friend class CScriptDataMgr;	// 只有CScriptDataMgr能实例化
	friend class CLandedTitlesData;		// 开放给它遍历一次map 以后都只会用指针来访问Property了
public:
	~CLandedTitlesProperty() = default;
private:
	CLandedTitlesProperty() = default;
	CLandedTitlesProperty(const CLandedTitlesProperty&) = delete;
	CLandedTitlesProperty& operator=(const CLandedTitlesProperty&) = delete;

	bool IsDataComplete() const;	// 检查map中所有数据是否都不为空

private:
	std::unordered_map<std::wstring, _stLandedTitlesProperty> m_mapLandedTitlesProperty;		// 储存所有读取的省份信息    虽然只会被遍历一次 但因为_stLandedTitlesProperty的拷贝构造函数而不能用list
};
